<!DOCTYPE html>
<html>
<head>
    <title>实时波形显示 - 20ms间隔</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        body { 
            font-family: Arial, sans-serif; 
            margin: 0; 
            padding: 20px; 
            background-color: #f5f5f5;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 { 
            color: #333; 
            text-align: center;
            margin-bottom: 20px;
        }
        .controls { 
            margin: 20px 0; 
            display: flex;
            gap: 15px;
            align-items: center;
            justify-content: center;
        }
        button {
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-weight: bold;
        }
        #startBtn {
            background-color: #4CAF50;
            color: white;
        }
        #stopBtn {
            background-color: #f44336;
            color: white;
        }
        #status {
            padding: 10px;
            background: #eee;
            border-radius: 5px;
            min-width: 120px;
            text-align: center;
        }
        .stats {
            display: flex;
            gap: 20px;
            justify-content: center;
            margin: 15px 0;
            font-size: 14px;
            color: #666;
        }
        .stat-item {
            background: #f8f9fa;
            padding: 8px 15px;
            border-radius: 5px;
            border-left: 4px solid #4CAF50;
        }
        #chart-container { 
            width: 100%; 
            height: 70vh; 
            margin-top: 20px;
        }
        .connected { background-color: #d4edda; color: #155724; }
        .disconnected { background-color: #f8d7da; color: #721c24; }
        .connecting { background-color: #fff3cd; color: #856404; }
    </style>
</head>
<body>
    <div class="container">
        <h1>实时波形显示器 (16位精度, 1000Hz采样率, 20ms间隔)</h1>
        
        <div class="stats">
            <div class="stat-item">数据间隔: <span id="interval">20ms</span></div>
            <div class="stat-item">采样率: <span id="sampleRate">1000Hz</span></div>
            <div class="stat-item">数据点: <span id="pointCount">0</span></div>
            <div class="stat-item">更新时间: <span id="lastUpdate">-</span></div>
        </div>
        
        <div class="controls">
            <button id="startBtn">开始连接</button>
            <button id="stopBtn">停止连接</button>
            <span id="status" class="disconnected">状态: 未连接</span>
            <button id="pingBtn">发送Ping</button>
        </div>
        
        <div id="chart-container">
            <canvas id="waveformChart"></canvas>
        </div>
    </div>

    <script>
        // 初始化Chart.js
        const ctx = document.getElementById('waveformChart').getContext('2d');
        const chart = new Chart(ctx, {
            type: 'line',
            data: {
                datasets: [{
                    label: '波形数据',
                    borderColor: 'rgb(75, 192, 192)',
                    backgroundColor: 'rgba(75, 192, 192, 0.1)',
                    borderWidth: 1.5,
                    pointRadius: 0,
                    fill: true,
                    tension: 0.4,
                    data: []
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    x: {
                        type: 'linear',
                        position: 'bottom',
                        title: { 
                            display: true, 
                            text: '时间 (ms)',
                            font: { weight: 'bold' }
                        },
                        grid: {
                            color: 'rgba(0,0,0,0.1)'
                        }
                    },
                    y: {
                        min: -32768,
                        max: 32767,
                        title: { 
                            display: true, 
                            text: '幅值',
                            font: { weight: 'bold' }
                        },
                        grid: {
                            color: 'rgba(0,0,0,0.1)'
                        }
                    }
                },
                plugins: {
                    legend: {
                        display: true,
                        position: 'top'
                    }
                },
                animation: {
                    duration: 0
                }
            }
        });

        // WebSocket连接管理
        let ws = null;
        let dataBuffer = [];
        const maxPoints = 1000; // 显示1000个点(1秒数据)
        let timeCounter = 0;
        let reconnectAttempts = 0;
        const maxReconnectAttempts = 10;
        let reconnectTimer = null;
        let lastUpdateTime = null;
        let receivedDataCount = 0;

        // 更新统计信息
        function updateStats() {
            document.getElementById('pointCount').textContent = dataBuffer.length;
            document.getElementById('lastUpdate').textContent = lastUpdateTime ? 
                new Date(lastUpdateTime).toLocaleTimeString() : '-';
        }

        // 连接WebSocket
        function connectWebSocket() {
            if (ws) {
                ws.close();
            }
            
            // 清除重连定时器
            if (reconnectTimer) {
                clearTimeout(reconnectTimer);
                reconnectTimer = null;
            }
            
            // 更新状态
            document.getElementById('status').textContent = '状态: 连接中...';
            document.getElementById('status').className = 'connecting';
            
            ws = new WebSocket(`ws://${window.location.host}/ws`);
            
            ws.onopen = () => {
                document.getElementById('status').textContent = '状态: 已连接';
                document.getElementById('status').className = 'connected';
                console.log('WebSocket连接已建立');
                reconnectAttempts = 0;
                
                // 重置数据
                dataBuffer = [];
                timeCounter = 0;
                chart.data.datasets[0].data = [];
                chart.update('none');
            };
            
            ws.onclose = (event) => {
                document.getElementById('status').textContent = '状态: 已断开';
                document.getElementById('status').className = 'disconnected';
                console.log('WebSocket连接已关闭', event.code, event.reason);
                
                // 自动重连逻辑
                if (reconnectAttempts < maxReconnectAttempts) {
                    reconnectAttempts++;
                    const delay = Math.min(1000 * reconnectAttempts, 10000);
                    console.log(`将在 ${delay}ms 后尝试重连 (尝试 ${reconnectAttempts}/${maxReconnectAttempts})`);
                    
                    reconnectTimer = setTimeout(() => {
                        console.log('尝试重新连接...');
                        connectWebSocket();
                    }, delay);
                }
            };
            
            ws.onerror = (error) => {
                console.error('WebSocket错误:', error);
                document.getElementById('status').textContent = '状态: 连接错误';
                document.getElementById('status').className = 'disconnected';
            };
            
            ws.onmessage = (event) => {
                lastUpdateTime = Date.now();
                receivedDataCount++;
                
                // 处理心跳消息
                if (event.data === 'ping') {
                    console.log('Received ping from server');
                    ws.send('pong');
                    return;
                }
                
                try {
                    const data = JSON.parse(event.data);
                    
                    if (data.type === 'waveform') {
                        // 更新统计信息
                        if (data.interval_ms) {
                            document.getElementById('interval').textContent = data.interval_ms + 'ms';
                        }
                        if (data.sample_rate) {
                            document.getElementById('sampleRate').textContent = data.sample_rate + 'Hz';
                        }
                        
                        // 处理波形数据
                        data.data.forEach(value => {
                            dataBuffer.push({x: timeCounter, y: value});
                            timeCounter += 1; // 1ms间隔
                        });
                        
                        // 保持数据量不超过maxPoints
                        if (dataBuffer.length > maxPoints) {
                            dataBuffer = dataBuffer.slice(dataBuffer.length - maxPoints);
                        }
                        
                        // 更新图表
                        chart.data.datasets[0].data = dataBuffer;
                        chart.update('none');
                        
                        // 更新统计信息
                        updateStats();
                    } else if (data.type === 'heartbeat') {
                        console.log('Received heartbeat from server');
                        // 可选：响应服务器心跳
                        ws.send(JSON.stringify({
                            type: 'heartbeat_ack', 
                            timestamp: Date.now()
                        }));
                    }
                } catch (e) {
                    console.error('消息解析错误:', e, event.data);
                }
            };
        }

        // 发送ping到服务器
        function sendPing() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.send('ping');
                console.log('Sent ping to server');
            } else {
                console.log('无法发送ping: WebSocket未连接');
            }
        }

        // 页面卸载时清理
        window.addEventListener('beforeunload', () => {
            if (reconnectTimer) {
                clearTimeout(reconnectTimer);
            }
            if (ws) {
                ws.close();
            }
        });

        // 按钮事件
        document.getElementById('startBtn').addEventListener('click', connectWebSocket);
        document.getElementById('stopBtn').addEventListener('click', () => {
            if (ws) {
                ws.close();
                console.log('手动关闭连接');
            }
            if (reconnectTimer) {
                clearTimeout(reconnectTimer);
                reconnectTimer = null;
            }
        });
        document.getElementById('pingBtn').addEventListener('click', sendPing);

        // 页面加载时自动连接
        connectWebSocket();

        // 定期更新统计信息
        setInterval(updateStats, 1000);

        // 可选：定期发送ping保持连接活跃
        setInterval(sendPing, 15000);
    </script>
</body>
</html>